\chapter{中断处理}

\section{概述}
Tenon中的中断处理提供了一种在正常顺序执行逻辑之外根据事件触发的函数调用方式。
Tenon的中断处理架构涉及两个方面：中断处理函数，中断变量。

\section{中断处理函数}
中断处理函数包含了中断处理逻辑。中断处理函数必须没有参数也没有返回值。中断处理函数可以调用其他函数。

\section{中断变量}

中断变量是intnum类型的模块变量，不能是常量或持久量。
中断变量是中断的标识，对已建立的中断的各种操作都通过中断变量进行。

使用connect语句建立中断变量和中断处理函数的连接关系。一个中断变量只能连接一个中断处理函数，
但一个中断处理函数可以有多个中断变量连接到它。

\section{中断的订阅}

在创建中断变量，并建立该中断变量和中断处理函数的连接关系之后，该中断变量可以被用来订阅中断。
中断的订阅即将中断变量用于标识某种中断事件。

中断事件可以分为以下类别：IO信号变更，持久量值变更，定时器耗尽等。
其中，IO信号又分为数字输入信号（DI）、数字输出信号（DO）、数字IO组输入信号（GI）、
数字IO组输出信号（GO）、模拟输入信号（AI）、模拟输出信号。

IO相关的中断订阅函数需要由机器人控制器来具体实现，在语言层面不做具体规定。Tenon语言提供
计时器中断和持久量中断的订阅函数。

中断在订阅后都是使能的。可以同时禁止或重新使能所有中断，也可以禁止或重新使能单个中断。
idisable/ienable用于同时禁止/重新使能所有中断；isleep/iwatch用于禁止/使能单个中断。

idelete可以删除一个中断，它会同时删除中断事件和中断变量的绑定以及中断变量和中断处理函数的连接关系。
  
以itimer为例，其原型如下：
  
\begin{verbatim}
opaque void itimer(num interval, intnum& interrupt, singlemode mode = singlemode.cyclic);
\end{verbatim}
  
使用itimer指令时，需要提供一个中断变量interrupt，以及定时间隔interval和定时模式mode。
itimer会启动一个定时器，并指定定时时间到达时的中断服务例程为中断变量interrupt所连接的中断服务例程。

\section{中断处理函数的错误处理器}
中断处理函数也可以有自己的错误处理器。由于中断处理函数的调用不属于正常函数调用栈的一部分，
所以中断处理函数的错误处理器抛出的错误会直接交给系统错误处理器处理。

\section{中断处理过程}
当程序执行的时候，所有发生的中断都会进入一个队列。系统会在一条底层指令执行完毕之后检查中断队列，
依次执行其中中断对应的中断处理函数。当系统在执行中断处理函数的时候，不会响应其他的中断处理。而要等到
当前中断处理函数执行完毕之后，再检查中断队列中的下一个中断。

当中断队列执行完毕之后，系统会接着执行正常执行逻辑中的下一条底层指令。
